//
// Created by pzw on 24-3-12.
//

#include <cassert>
#include "UnmodifySeq.h"

UnmodifySeq::UnmodifySeq() = default;

UnmodifySeq::~UnmodifySeq() = default;

/**
 * for_each是最简单的算法
 *
 * @tparam E - 模板参数
 * @param v  - 要遍历的数据
 */
template<typename E>
void UnmodifySeq::for_each(std::vector<E> &v) {
    std::for_each(v.begin(), v.end(), [](int x) -> void {
        std::cout << "for_each: x = " << x << std::endl;
    });
}

template<typename E>
std::vector<E> UnmodifySeq::sequence_predicate(const std::vector<E> &val, const std::vector<E> &div) {
    assert(val.size() < div.size());
    assert(all_of(div.begin(), div.end(), [](double x) -> bool {
        return 0 < x;
    }));
    std::vector<E> res(val.size());
    for (int i = 0; i < val.size(); ++i) {
        res[i] = val[i] / div[i];
    }
    return res;
}

void UnmodifySeq::std_count_space(const std::string &text) {
    const char char_space = ' ';
    long n_space = std::count(text.begin(), text.end(), char_space);
    long n_whitespace = std::count_if(text.begin(), text.end(), isspace);
    std::cout << "std_count_space text: n_space = " << n_space << ", n_whitespace = " << n_whitespace << std::endl;
}

void UnmodifySeq::std_find_space(const std::string &text) {
    const char char_space = ' ';
    auto n_space = std::find(text.begin(), text.end(), char_space);
    const std::basic_string<char, std::char_traits<char>, std::allocator<char>>::const_iterator &n_whitespace
            = std::find_if(text.begin(), text.end(), isspace);
    std::cout << "std_find_space text: n_space = " << *n_space << ", n_whitespace = " << *n_whitespace << std::endl;
}

void UnmodifySeq::std_find_first_of(std::array<int, 3> x, std::array<int, 5> y) {
    auto p = std::find_first_of(x.begin(), x.end(), y.begin(), y.end());
    auto q = std::find_first_of(p + 1, x.end(), y.begin(), y.end());
    std::cout << "std_find_first_of: p = " << *p << ", q = " << *q << std::endl;
}

void UnmodifySeq::std_equal_mismatch(std::vector<int> vec, std::vector<int> vec2) {
    // std::equal示例
    if (std::equal(vec.begin(), vec.end(), vec2.begin())) {
        std::cout << "vec和vec2相等" << std::endl;
    } else {
        std::cout << "vec和vec2不相等" << std::endl;
    }

    // std::mismatch示例
    using namespace std;
    const pair<vector<int>::iterator, vector<int>::iterator> &pair
            = mismatch(vec.begin(), vec.end(), vec2.begin());
    if (pair.first == vec.end()) {
        cout << "vec和vec2完全相等" << endl;
    } else {
        cout << "vec和vec2第一个不相等的元素是: " << *pair.first << " 和 " << *pair.second << endl;
    }
}

bool UnmodifySeq::std_search_in_quote(const std::string &quote, const std::string &text) {
    using namespace std;
    auto p = search(quote.begin(), quote.end(), text.begin(), text.end());
    return p != quote.end();
}

int UnmodifySeq_main() {
    UnmodifySeq *unmodifySeq = new UnmodifySeq();
    std::vector<int> v{0 * 10, 1 * 10, 2 * 10, 3 * 10, 4 * 10, 5 * 10, 6 * 10, 7 * 10};
    std::vector<int> v2{1, 2, 3, 4, 5, 6, 7, 8, 9};

    unmodifySeq->for_each(v);

    const std::vector<int> &res = unmodifySeq->sequence_predicate(v, v2);
    for (auto it = res.begin(); it != res.end(); it++) {
        std::cout << "UnmodifySeq_main: it = " << (*it) << std::endl;
    }

    UnmodifySeq::std_count_space("1qaz 2wsx 3edc 4rfv 5tgb 6yhn 7ujm");
    UnmodifySeq::std_find_space("1qaz 2wsx 3edc 4rfv 5tgb 6yhn 7ujm");
    UnmodifySeq::std_find_first_of({1, 3, 4}, {0, 2, 3, 4, 5});
    UnmodifySeq::std_equal_mismatch({1, 2, 3, 4, 5}, {1, 2, 3, 4, 5});

    std::string quote{"Why waste time learning, when ignorance is instantaneous?"};
    bool b1 = UnmodifySeq::std_search_in_quote(quote, "learning");
    bool b2 = UnmodifySeq::std_search_in_quote(quote, "lemming");
    std::cout << "UnmodifySeq_main: b1 = " << b1 << ", b2 = " << b2 << std::endl;
    
    delete unmodifySeq;
    return 0;
}
